**************************************************************************************
	;Header frs File-linken

	IFD	Flag_project
Flag_scroll	set 1
	ENDC
	IFND	Flag_scroll
Flag_scroll	set 0
	ENDC
	IFEQ	Flag_scroll
Flag_scroll	set 1
	include	Nutz_project
	ELSEIF
**************************************************************************************
SCR_MODULE_FLIP	EQU	3
SCR_KOLLISION_BIT	EQU	2
SCR_SRG_BIT	EQU	1
SCR_EFFECT_BIT	EQU	0

Init_Scroll:
	clr.w	Scr_X_Supply_Adr(a6)
	clr.w	Scr_Y_Supply_Adr(a6)
	clr.w	Scr_X_Speed(a6)
	clr.w	Scr_Y_Speed(a6)
	move.w	#-1,Scr_X_Mask(a6)
	move.w	#16,Scr_X_Min(a6)
	rts

;-------------- Scrolling A Handler ------------------
Scroll:
	move.w	Scr_X_Level_Pos(a6),Scr_X_Level_Pos_Old(a6)
	move.w	Scr_Y_Level_Pos(a6),Scr_Y_Level_Pos_Old(a6)

	bsr	Scroll_X

	move.w	Scr_X_Mask(a6),d0			;Fr die Warpzone
	and.w	d0,Scr_X_Level_Pos(a6)			; "   "     "

	;Wurde eine 8er Grenze berschritten ?

	move.w	Scr_X_Level_Pos_Old(a6),d0
	and.w	#$fff8,d0
	move.w	Scr_X_Level_Pos(a6),d1
	and.w	#$fff8,d1
	cmp.w	d0,d1
	beq.s	.no_x_scroll

	tst	Scr_X_Speed(a6)
	beq	.no_x_scroll
	bpl	.scroll_to_left

	bsr	supply_left
	bra.s	.no_x_scroll

.scroll_to_left:
	bsr	supply_right

.no_x_scroll:

	bsr	Scroll_Y

	move.w	Scr_Y_Level_Pos_Old(a6),d0
	and.w	#$fff8,d0
	move.w	Scr_Y_Level_Pos(a6),d1
	and.w	#$fff8,d1
	cmp.w	d0,d1
	beq.s	.no_y_scroll

	tst	Scr_Y_Speed(a6)
	beq	.no_y_scroll
	bpl	.scroll_to_down
	bsr	supply_up
	bra.s	.no_y_scroll
.scroll_to_down:
	bsr	supply_down
.no_y_scroll:

	rts

supply_down:
	move	Scr_Y_Level_Pos(a6),d0
	asr	#3,d0
	add	#28,d0
	and	#31,d0
	asl	#7,d0

	add	#$e000,d0

	move	d0,Scr_Y_Supply_Adr(a6)

	move	Scr_X_Level_Pos(a6),d4
	asr	#4,d4
	subq.w	#2,d4
	move	Scr_Y_Level_Pos(a6),d5
	asr	#4,d5
	add.w	#14,d5

	lea	Scr_Y_Supply_Buffer(a6),a5
	lea	Scr_Macros(a6),a1

	move	Scr_Y_Level_Pos(a6),d1
	lsr	#3,d1
	and	#1,d1
	asl.w	#2,d1
	lea	(a1,d1.w),a1

	move	Scr_X_Level_Pos(a6),d6
	lsr	#2,d6
	add.w	#120,d6
	and	#124,d6

	moveq	#22,d7
.loopx:
	bsr	Get_Scr_Macro
	bsr	write_macro_row
	addq.w	#1,d4
	dbf	d7,.loopx

	rts

supply_up:
	move	Scr_Y_Level_Pos(a6),d0
	asr	#3,d0
	subq	#2,d0
	and	#31,d0
	asl	#7,d0

	add	#$e000,d0

	move	d0,Scr_Y_Supply_Adr(a6)

	move	Scr_X_Level_Pos(a6),d4
	asr	#4,d4
	subq.w	#2,d4
	move	Scr_Y_Level_Pos(a6),d5
	asr	#4,d5
	subq.w	#1,d5
	lea	Scr_Y_Supply_Buffer(a6),a5
	lea	Scr_Macros(a6),a1

	move	Scr_Y_Level_Pos(a6),d1
	lsr	#3,d1
	and	#1,d1
	asl.w	#2,d1
	lea	(a1,d1.w),a1

	move	Scr_X_Level_Pos(a6),d6
	lsr	#2,d6
	add.w	#120,d6
	and	#124,d6

	moveq	#22,d7
.loopx2:
	bsr	Get_Scr_Macro
	bsr	write_macro_row
	addq.w	#1,d4
	dbf	d7,.loopx2
	rts


supply_right:
	move	Scr_X_Level_Pos(a6),d0
	asr	#3,d0
	add	#40,d0
	and	#63,d0
	add	d0,d0

	add	#$e000,d0

	move	d0,Scr_X_Supply_Adr(a6)

	move	Scr_X_Level_Pos(a6),d4
	asr	#4,d4
	move	Scr_Y_Level_Pos(a6),d5
	asr	#4,d5
	subq.w	#1,d5
	add	#20,d4

	lea	Scr_X_Supply_Buffer(a6),a5
	lea	Scr_Macros(a6),a1

	move	Scr_X_Level_Pos(a6),d1
	lsr	#3,d1
	and	#1,d1
	add	d1,d1

	lea	(a1,d1.w),a1

	move	Scr_Y_Level_Pos(a6),d6
	lsr	#2,d6
	add.w	#60,d6
	and	#60,d6

	moveq	#15,d7
.loopy:
	bsr	Get_Scr_Macro

	bsr	write_macro_line

	addq.w	#1,d5
	dbf	d7,.loopy

	rts

supply_left:
	move	Scr_X_Level_Pos(a6),d0
	asr	#3,d0
	subq	#4,d0
	and	#63,d0
	add	d0,d0

	add	#$e000,d0

	move	d0,Scr_X_Supply_Adr(a6)		; An dieser X-Pos wird die Grafik eingetragen.

	move	Scr_X_Level_Pos(a6),d4
	asr	#4,d4
	move	Scr_Y_Level_Pos(a6),d5
	asr	#4,d5
	subq.w	#1,d5
	subq	#2,d4

	lea	Scr_X_Supply_Buffer(a6),a5
	lea	Scr_Macros(a6),a1

	move	Scr_X_Level_Pos(a6),d1
	lsr	#3,d1
	and	#1,d1
	add	d1,d1

	lea	(a1,d1.w),a1

	move	Scr_Y_Level_Pos(a6),d6
	lsr	#2,d6
	add.w	#60,d6
	and	#60,d6

	moveq	#15,d7

.loopy2:
	bsr	Get_Scr_Macro

	bsr	write_macro_line

	addq.w	#1,d5
	dbf	d7,.loopy2

	rts

write_macro_line:
	asl	#3,d0

	lea	(a1,d0.w),a2

	btst	#SCR_MODULE_FLIP,d3
	beq.s	.no_yflip

	move	4(a2),d2
	or.w	#$1000,d2
	move.w	d2,0(a5,d6)
	addq	#2,d6
	and	#62,d6
	move	(a2),d2
	or.w	#$1000,d2
	move.w	d2,0(a5,d6)
	addq	#2,d6
	and	#62,d6
	rts
.no_yflip:
	move	(a2),0(a5,d6)
	addq	#2,d6
	and	#62,d6
	move	4(a2),0(a5,d6)
	addq	#2,d6
	and	#62,d6

	rts

	;Frs Vertikale Scrolling Macro-Zeile bearbeiten.

write_macro_row:
	and.w	#$ff,d0
	asl	#3,d0

	btst	#SCR_MODULE_FLIP,d3
	beq.s	.no_yflip2
	move.l	a1,d2
	eor.w	#4,d2
	move.l	d2,a2
	move.w	#$1000,d2

	lea	(a2,d0),a2
	move.w	(a2)+,d0
	or.w	d2,d0
	move.w	d0,(a5,d6)
	addq	#2,d6
	and	#126,d6
	move.w	(a2)+,d0
	or.w	d2,d0
	move.w	d0,(a5,d6)
	addq	#2,d6
	and	#126,d6
	rts

.no_yflip2:
	lea	(a1,d0),a2
	move.w	(a2)+,(a5,d6)
	addq	#2,d6
	and	#126,d6
	move.w	(a2)+,(a5,d6)
	addq	#2,d6
	and	#126,d6
	rts


Scroll_X:
	move.w	Scr_X_Min(a6),d2	;Linke Grenze
	move.w	Scr_Level_Width(a6),d3	;Rechte Grenze
	sub.w	#20,d3
	asl.w	#4,d3
	move.w	Scr_X_Speed(a6),d0	;Speed
	move.w	Scr_X_Level_Pos(a6),d1	;Alte Pos

	bsr	check_speed_frames	;richtige Geschwindigkeit abchecken.

	move.w	d0,Scr_X_Speed(a6)
	move.w	d0,Scr_X_Real_Speed(a6)
	add.w	d0,Scr_X_Level_Pos(a6)
	rts

Scroll_Y:
	moveq	#0,d2			;Linke Grenze
	move.w	Scr_Y_Max(a6),d3	;Rechte Grenze
	sub.w	#16,d3
	move.w	Scr_Y_Speed(a6),d0	;Speed
	move.w	Scr_Y_Level_Pos(a6),d1	;Alte Pos

	bsr	check_speed_frames	;richtige Geschwindigkeit abchecken.

	move.w	d0,Scr_Y_Speed(a6)
	move.w	d0,Scr_Y_Real_Speed(a6)
	add.w	d0,Scr_Y_Level_Pos(a6)
	rts

	;IN:
	;d0	Speed
	;d1	Alte Pos
	;d2	untere Grenze
	;d3	obere Grenze

	;OUT:
	;d0	korrekte Speed

	;SCRATCH:
	;d4
check_speed_frames:
	move.w	d0,d4
	add.w	d1,d4			;Neue Position
	cmp.w	d2,d4			;Ist die Neue Pos kleiner als die untere Grenze ?
	bge.s	.lower_ok		;Nein, es ist OK
	sub.w	d1,d2			;Die Speed ist:
	move.w	d2,d0			; Speed=OldPos-LowerBorder
	rts
.lower_ok:

	cmp.w	d3,d4			;Neue Pos grer als obere Grenze ?
	ble.s	.upper_ok		;Nein, Speed ist OK
	sub.w	d1,d3			;Die Speed ist
	move.w	d3,d0			; Speed=UpperBorder-OldPos
.upper_ok:
	rts

;-------------- Kopiert die von der Scroll-Routine angegebenen Daten ins VRam.

ScrollDataSet:
	lea	$c00000,a0

	move	Scr_X_Level_Pos(a6),d0
	neg	d0
	move.w	d0,d1
	swap	d0
	move.w	d1,d0

	move.l	#$8f048f04,4(a0)
	btst	#1,Scr_SplitScroll(a6)
	beq.s	.x_full_scroll

	move.l	#$40000000+$30000003,4(a0)
	move.w	#224/4-1,d7
.hcopy:
	move.l	d0,(a0)
	move.l	d0,(a0)
	dbf	d7,.hcopy

	bra.s	.x_done

.x_full_scroll:
	move.l	#$40000000+$30000003,4(a0)
	move.w	d0,(a0)

.x_done:
	btst	#0,Scr_SplitScroll(a6)		;Y-Full-scroll ?
	beq.s	.y_full_scroll
	move.w	#$8f04,4(a0)

	move.w	Scr_Y_Level_Pos(a6),d0
	moveq	#19,d7
	move.l	#$40000010+$00000000,$c00004
.vcopy:
	move.w	d0,(a0)
	dbf	d7,.vcopy
	bra.s	.yscroll_done

.y_full_scroll:
	move.l	#$40000010+$00000000,4(a0)
	move	Scr_Y_Level_Pos(a6),(a0)

.yscroll_done:
	move	Scr_X_Supply_Adr(a6),d0
	beq.s	.no_x_supply

	move	#$8f80,4(a0)		; Senkrecht eintragen!
	bsr	SetVRamAdress
	lea	Scr_X_Supply_Buffer(a6),a0
	moveq	#31,d1
.xcopy:
	move	(a0)+,$c00000
	dbf	d1,.xcopy

	clr	Scr_X_Supply_Adr(a6)

.no_x_supply:
	move	Scr_Y_Supply_Adr(a6),d0
	beq.s	.no_y_supply

	move	#$8f02,$c00004		; Senkrecht eintragen!
	bsr	SetVRamAdress
	lea	Scr_Y_Supply_Buffer(a6),a0
	moveq	#63,d1
.ycopy:
	move	(a0)+,$c00000
	dbf	d1,.ycopy

	clr	Scr_Y_Supply_Adr(a6)

.no_y_supply:
	rts

;-------------- Creiert Display an der in Level_Pos bestimmten Position!

Create_Playfield:
	move.w	sr,-(sp)
	move.w	#$8124,$c00004		;Display aus, frs scrollen.

	move.w	Scr_X_Level_Pos(a6),d0
	add.w	#512,d0
	move.w	Scr_Level_Width(a6),d3	;Rechte Grenze
	sub.w	#20,d3
	asl.w	#4,d3
	cmp.w	d3,d0
	bge	.to_right

	add.w	#512,Scr_X_Level_Pos(a6)
	clr.w	Scr_Y_Speed(a6)

	moveq	#128-1,d7
.loop:
	move.l	d7,-(sp)

.wait:
	btst	#1,$c00004
	beq.s	.wait

	bsr	ScrollDataSet

	move.w	Scr_X_Level_Pos(a6),Scr_X_Level_Pos_Old(a6)
	subq.w	#4,Scr_X_Level_Pos(a6)

	bsr	supply_left

	bsr	Area_Check

	move.l	(sp)+,d7

	dbf	d7,.loop

	bsr	ScrollDataSet

	move.w	Glo_Display(a6),$c00004		;Display an.

	rte

.force_right:
	sub.w	#512,Scr_X_Level_Pos(a6)
	bra.s	.right_in
.to_right:
	move.w	Scr_X_Level_Pos(a6),d0
	sub.w	#512,d0
	bmi.s	.to_down
	move.w	d0,Scr_X_Level_Pos(a6)
.right_in:
	clr.w	Scr_Y_Speed(a6)

	moveq	#128-1,d7
.loopr:
	move.l	d7,-(sp)

.waitr:
	btst	#1,$c00004
	beq.s	.waitr

	bsr	ScrollDataSet

	move.w	Scr_X_Level_Pos(a6),Scr_X_Level_Pos_Old(a6)
	addq.w	#4,Scr_X_Level_Pos(a6)

	bsr	supply_right

	bsr	Area_Check

	move.l	(sp)+,d7

	dbf	d7,.loopr

	bsr	ScrollDataSet

	move.w	#$8164,$c00004		;Display an.

	rte

.to_down:
	cmp.w	#0,Glo_Level(a6)
	beq	.force_right
	moveq	#72-1,d7
	move.w	Scr_Y_Level_Pos(a6),d0
	sub.w	#288,d0
;	cmp.w	#-32,d0
;	bgt.s	.do_it

;	add.w	#36+44,d0
;	bmi.s	.force_right
;	moveq	#52-1,d7

.do_it:
	move.w	d0,Scr_Y_Level_Pos(a6)
	clr.w	Scr_X_Speed(a6)
.loopd:
	move.l	d7,-(sp)
.waitd:
	btst	#1,$c00004
	beq.s	.waitd

	bsr	ScrollDataSet

	move.w	Scr_Y_Level_Pos(a6),Scr_Y_Level_Pos_Old(a6)
	addq.w	#4,Scr_Y_Level_Pos(a6)

	bsr	supply_down

	bsr	Area_Check

	move.l	(sp)+,d7

	dbf	d7,.loopd

	bsr	ScrollDataSet

	move.w	#$8164,$c00004		;Display an.

	rte

	;Macro an der Level-pos X/Y (in Macros) einlesen

	;INPUT :
	;d4	= X-Pos
	;d5	= Y-Pos

	;OUTPUT:
	;d0	= Macro und FXbits

	;Scratch-Register :

	;a0

Get_Scr_Macro:
	movem.l	d4/d5,-(sp)

	add.w	d5,d5
	lea	Block_Table(a6),a0
	move.w	(a0,d5.w),d5
	add.w	d4,d5
	move	d5,d4
	lsr.w	#1,d4
	move.l	Scr_Level(a6),a0
	moveq	#0,d0
	move.b	(a0,d5.w),d0
	move.l	Scr_Level_Bits(a6),a0
	move.b	(a0,d4.w),d3
	and	#1,d5
	beq.s	.Gerade
.UnGerade	*--*>Shift Down
	and.w	#$000f,d3
	bra.s	.Weiter
.Gerade	*--*>Ausmaskieren
	and.w	#$00f0,d3
	lsr.w	#4,d3
.Weiter
	movem.l	(sp)+,d4/d5
	rts

	ENDC